import threading, socket, sppt, time
from select import select

class socket_ev(threading.Thread):
	def __init__(self, onrecv, onsending, onsend, ondisconnect, socket=None, name="", timeout=420):
		self.ev_onrecv = onrecv
		self.ev_onsend = onsend
		self.ev_onsending = onsending
		self.ev_ondisconnect = ondisconnect
		self.socket = socket
		self.execute = True
		self.connected = True
		self.timeout = timeout
		self.sock_name = name
		self.block = False
		
		self.p_null = None #'\xff\x00\x04\x00'
		
		self.data = ""
		
		threading.Thread.__init__(self)
		self.start()

	def disconnect(self, reason=""):
		try:
			self.socket.close()
		except: pass
		self.ev_ondisconnect(self, reason)
		self.connected = False
		sppt.write("Socket closed: %s" % reason)
		
	def send(self, data):
		try:
			self.block = False
			self.ev_onsending(self, data)
			time.sleep(0.05)
			if (self.block == True):
				return None
			self.socket.sendall(data)
			self.ev_onsend(self, data)
		except:
			self.disconnect("Could not send data")
		
	def run(self):
		time.sleep(0.05)
		sppt.write("Thread started")
		while self.execute:
			while self.connected:
				r = select([self.socket], [], [self.socket], self.timeout)
				
				# check socket state
				if r[0] == []:
					if (self.p_null != None):
						self.socket.sendall(self.p_null)
				if self.socket in r[2]: #Error
					self.disconnect("Stream read error")
					break
					
				# recv
				try:
					data = self.socket.recv(2048)
					if not self.connected:
						break
					self.data += data
				except:
					raise
					self.disconnect("Stream reached end")
					break
					
				# process
				if len(self.data) > 0:
					self.ev_onrecv(self, self.data)
					self.data = ""
					
				time.sleep(0.04)

		
	